In computer systems, and in particular, as part of computer operating systems and software development environments, tools may be provided to allow the “loading” and “linking” of “software modules” (e.g., object files) for execution, for example, as part of an application program. Such software modules may include instructions and/or data structures, each positioned at particular locations in the software module. Instructions in software modules may make references to instructions or data structures both inside and outside of the software module (for example, in another software module). “Linking” involves “resolving” these references, so that an instruction making a reference will include the location of the instruction or data structure to be accessed.
References are typically indicated by “symbols” used to represent the desired location. The resolution process includes “defining” a symbol—assigning a value (e.g., a memory address) to the symbol by the software module that contains the locations to which access is to be allowed—and then substituting the symbol value for any references to the symbol used in other software modules.
In previous linking implementations, software modules needed to be linked in an order such that the symbol definition was established before the symbol was referenced by the software module being linked. For example, if a symbol “A1B2C3” were referenced in a particular software module, the symbol “A1B2C3” must have been defined by a previously loaded software module, so that a value for the symbol would be known by the linker. Where the symbol was not previously defined, the linker could abort the linking process, or could simply skip the resolution step for the particular symbol, leaving a “dangling” reference in the software module being linked—the instructions using the symbol reference would contain an undefined value for the memory location to access. Dangling references may cause abnormal execution (since they are undefined), and may cause corruption of other parts of the system.
Moreover, once a set of software modules has been completely linked, it heretofore has been extremely difficult to “unlink” one or more of the set of software modules without compromising the integrity of the application using the software module or the system itself. Once software modules are linked, the linker generally discards all information about the linking process in order to conserve memory (information that is not necessary during execution), including any symbols used during linking. Thus, removing a particular software module from a linked set of software modules can result in dangling references by instructions to the (now removed) software module, resulting in the same problems discussed above.